// This is the main DLL file.

#include "stdafx.h"

#include "..\Engine\Log.h"
#include "EngineTest2CLR.h"


namespace EngineTest2CLR {

using namespace System::Collections::Generic;

	// Engine wrapper class constructor
	CLREngineWrapper::CLREngineWrapper()
	{
		InitEngine();
		InternationalMoveGen::InitBitBoardGenerator();
	}

	 // Bitboard conversion methods
	///////////////////////////////////////////////////////////////////
	CLRBitBoard^ CLREngineWrapper::ToCLRBitBoard(BitBoard bb)
	{
		CLRBitBoard^ cbb = gcnew CLRBitBoard();
		cbb->wm = bb.wm;
		cbb->bm = bb.bm;
		cbb->wk = bb.wk;
		cbb->bk = bb.bk;

		return cbb;
	}

	CLRBitBoard64^ CLREngineWrapper::ToCLRBitBoard64(BitBoard64 bb)
	{
		CLRBitBoard64^ cbb = gcnew CLRBitBoard64();
		cbb->wm = bb.wm;
		cbb->bm = bb.bm;
		cbb->wk = bb.wk;
		cbb->bk = bb.bk;

		return cbb;
	}

	BitBoard CLREngineWrapper::ToEngineBitBoard(CLRBitBoard^ cbb)
	{
		BitBoard bb;
		bb.wm = cbb->wm;
		bb.bm = cbb->bm;
		bb.wk = cbb->wk;
		bb.bk = cbb->bk;

		return bb;
	}

	BitBoard64 CLREngineWrapper::ToEngineBitBoard64(CLRBitBoard64^ cbb)
	{
		BitBoard64 bb;
		bb.wm = cbb->wm;
		bb.bm = cbb->bm;
		bb.wk = cbb->wk;
		bb.bk = cbb->bk;

		return bb;
	}


	 // Logging functions
	//////////////////////////////////////////////////////////////////////////////
	int CLREngineWrapper::LogInit(String^ filename)
	{
		pin_ptr<const wchar_t> wchFileName = PtrToStringChars(filename);
		char szFileName[MAX_PATH];
		wcstombs(szFileName, wchFileName, MAX_PATH);

		return ::LogInit(szFileName);
	}

	void CLREngineWrapper::LogMessage(int logId, String^ msg)
	{
		pin_ptr<const wchar_t> wchMsg = PtrToStringChars(msg);
		::LogMessage(logId, wchMsg);	
	}

	void CLREngineWrapper::LogBB(int logId, CLRBitBoard^ cbb)
	{
		BitBoard bb = ToEngineBitBoard(cbb);
		::LogBB(logId, bb);
	}

	void CLREngineWrapper::LogBB64(int logId, CLRBitBoard64^ cbb)
	{
		BitBoard64 bb = ToEngineBitBoard64(cbb);
		::LogBB64(logId, bb);
	}

	void CLREngineWrapper::LogClose(int logId)
	{
		::LogClose(logId);
	}

 	 // bitboard generators proxy
	////////////////////////////////////////////////////////////////////////////////////

	array<CLRBitBoard^>^ CLREngineWrapper::EnglishBBGen(CLRBitBoard^ cbb, bool bWhite)
	{
		BitBoard bb = ToEngineBitBoard(cbb);

		BitBoard movelist[MAX_MOVES];
		int count = 0;
		count = EnglishMoveGen::GenerateBitBoardMoves(&bb, bWhite, movelist);

		List<CLRBitBoard^>^ list = gcnew List<CLRBitBoard^>();
		for(int i = 0; i < count; i++)
		{
			CLRBitBoard^ cbbMove = ToCLRBitBoard(movelist[i]);
			list->Add(cbbMove);
		}

		return list->ToArray();
	}

	array<CLRBitBoard64^>^ CLREngineWrapper::InternationalBBGen(CLRBitBoard64^ cbb, bool bWhite)
	{
		BitBoard64 bb = ToEngineBitBoard64(cbb);

		BitBoard64 movelist[MAX_MOVES];
		int count = 0;
		count = InternationalMoveGen::GenerateBitBoardMoves(&bb, bWhite, movelist);

		List<CLRBitBoard64^>^ list = gcnew List<CLRBitBoard64^>();
		for(int i = 0; i < count; i++)
		{
			CLRBitBoard64^ cbbMove = ToCLRBitBoard64(movelist[i]);
			list->Add(cbbMove);
		}

		return list->ToArray();
	}

}
